// 代理模式
package main

import "fmt"

type Goods struct {
	Kind string // 商品的种类
	Fact bool   // 商品的真伪
}

// ===== 抽象层 =====

type Shopping interface {
	Buy(goods *Goods) // 某任务
}

// ===== 实现层 =====

type KoreanShopping struct{}

func (ks *KoreanShopping) Buy(goods *Goods) {
	fmt.Println("去韩国进行了购物，买了", goods.Kind)
}

type AmericaShopping struct{}

func (as *AmericaShopping) Buy(goods *Goods) {
	fmt.Println("去美国进行了购物，买了", goods.Kind)
}

// ===== 代理层 =====

type OverseasShopping struct {
	shopping Shopping
}

func (op *OverseasShopping) Buy(goods *Goods) {
	op.ProxyBuy(goods)
}

func (op *OverseasShopping) ProxyBuy(goods *Goods) {
	if op.distinguish(goods) {
		op.shopping.Buy(goods)
		op.check(goods)
	}
}

// 辨别真伪的能力
func (op *OverseasShopping) distinguish(goods *Goods) bool {
	fmt.Println("对 [", goods.Kind, "] 进行了真伪辨别")
	if goods.Fact == false {
		fmt.Println(goods.Kind, "是假货")
	}
	return goods.Fact
}

// 安检流程
func (op *OverseasShopping) check(goods *Goods) {
	fmt.Println("对 [", goods.Kind, "] 进行了海关安检")
}

func NewProxy(shopping Shopping) Shopping {
	return &OverseasShopping{shopping: shopping}
}

// ===== 业务逻辑层 =====

func main() {
	g1 := &Goods{
		Kind: "iphone",
		Fact: true,
	}

	var kShopping Shopping = &KoreanShopping{}

	var proxy Shopping
	proxy = NewProxy(kShopping)

	proxy.Buy(g1)

}
